<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // ES5构造函数这种写法跟传统的面向对象语言（比如 C++ 和 Java）差异很大，很容易让新学习这门语言的程序员感到困惑。

    // ES6 提供了更接近传统语言的写法，引入了 Class（类）这个概念，作为对象的模板。通过class关键字，可以定义类。

    // 基本上，ES6 的class可以看作只是一个语法糖，它的绝大部分功能，ES5 都可以做到，新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已


    class Cat {  // 定义类名 (构造函数名)

        // 在class中提前声明(存储到实例化对象上),用于存储数据的属性
        posX = null;
        posY = null;

        // constructor  定义构造函数的执行内容
        constructor(name, color) {
            this.name = name;
            this.color = color;
        }

        // 小结: 
        // (1) class中定义的方法存储到对象原型(prototype)上
        // (2) class中定义的属性存储到实例化对象上
        // (3) class中定义的属性存储到实例化对象上,class中定义的方法存储到对象原型(prototype)上,如果在属性和方法前加前缀 # => 表示私有属性和私有方法 => 只能在class内访问,外部无法访问
        // (4) ES6 class中存在static 关键词,可以定义的属性和方法作为静态属性和方法存储到构造函数(类)上
        // (5) class中定义的属性 可以配置getter  setter

        static a = 1;
        static b = 2;
        static isCat(arg) {
            return arg.constructor === this;
        }

        // species = "Cat";
        #count = 0;

        // 定义对象原型(prototype)上的方法 (前面不需要加上function这个关键字，直接把函数定义放进去了就可以了。另外，方法与方法之间不需要逗号分隔，加了会报错。)
        hall() {
            console.log("喵喵", "老吴");
        }
        skill() {
            console.log("捉老鼠", "卖萌");
        }
        say() {
            console.log(this.name, this.color);
        }

        addCount() {
            this.#count ++;
        }
        reduceCount() {
            this.#count--;
        }

        // count属性
        get count() {  // 对count属性配置取值拦截
            return this.#count;
        }
        set count(val) {  // 对count属性配置赋值拦截
            this.#count = val;
        }


    }

    // 如果想把某个属性存储到构造函数的原型对象上 => 可以在class创建完毕手动添加
    // Cat.prototype.species = "Cat";


    console.dir(Cat)

    // 方便理解版
    /* Cat.prototype = {
        constructor() {

        },
        hall() {

        },
        skill() {

        },
        say() {

        }
    } */


    console.log(Cat.a);
    console.log(Cat.b);
    console.log(Cat.isCat(1));

    var Tom = new Cat("Tom", "black");
    console.log(Tom);


    Tom.addCount();
    Tom.addCount();
    Tom.addCount();
    Tom.addCount();
    console.log(Tom);

    Tom.reduceCount();
    console.log(Tom);

    console.log(Tom.count);

    Tom.count = 100;

    console.log(Tom.count);



</script>

</html>